上一篇介绍了zrender的总体结构,这一篇我们就详细介绍View层–Painter(Painter.js)。
一些demo和没有在博客中介绍的源码请进我的github仓库。
Painter利用canvas负责真正的绘图操作。
- 1.负责canvas及其周边DOM元素的创建与处理
- 2.负责调用各个Shape(预定义好的)进行绘制
- 3.提供基本的操作方法,渲染(render)、刷新(refresh)、尺寸变化(resize)、擦除(clear)等
1.渲染结构分析
两个例子都是渲染到div上。
1 | <div id="main" style="width:1000px;height:600px;margin:0;"></div> |
zrender 3.x版本渲染结果(demo/demo1/demo3-chart.html)
我们可以看到渲染结果都会新建一层div(从下面的分析我们可以得到这个div就是_domRoot
),里面嵌套canvas。如果有使用addHover(有hover层,data-zr-dom-id=”zr_100000”)的话,hover层会单独列一个canvas画布。1
2
3
4
5
6
7
8
9
10
11sector.on('mouseover', function() {
zr.addHover(this, {
stroke: 'yellow',
lineWidth: 10,
opacity: 1
});
zr.refresh();
});
sector.on('mouseout', function() {
zr.removeHover(this);
});
1 | <div id="main" style="width: 1000px; height: 600px; margin: 0px; -webkit-tap-highlight-color: transparent; user-select: none;"> |
2.构造函数
1 | var Painter = function (root, storage, opts) { |
3.Painter.prototype
1 | Painter.prototype = { |
我们再来回顾下整个渲染的过程:add
(zrender.js)–>addRoot
(Storage.js) –> addToMap
(Storage.js) –>dirty
[标记为脏的,下一帧渲染] (path.js) –> refresh
(Painter.js)–>_paintList
[遍历_displayList] (Painter.js)–>_doPaintEl
[渲染单个元素] Painter.js) –>brush
(Path.js)–>buildPath
(各个类型的shape)
refresh
刷新,刷新去绘制
1 | /** |
_paintList
1 | _paintList: function(list, paintAll) { |
_doPaintList
注意这里已经遍历了(遍历的是_displayList数组),所以后面的只针对单个元素绘制即可。1
2
3
4
5//... ...
for (var i = 0, l = list.length; i < l; i++) {
//... ...
this._doPaintEl(el, currentLayer, paintAll, scope);//绘制每个元素
}
_doPaintEl
1 | //... ... |
4.分析Painter对象
这一系列的操作是:
- 创建canvas外层包裹着_domRoot(div)
- canvas要绘制的东西都存储在storage中的_displayList数组中
- 遍历
_displayList
- 最后调用buildPath的canvas绘制。
5.Hover图层
如第1部分所见,如果增加了hover层(addHOver方法),那么会增加一层canvas,现在就来看这一层canvas是如何作用的。addHover
(zrender.js)–>
addHover
(zrender.js)
1 | addHover: function(el, style) { |
addHover
(Painter.js)
1 | addHover: function(el, hoverStyle) { |
我们在第三部分已经看到refresh
方法中的refreshHover
,渲染canvas时候,会渲染两个canvas,一个是主canvas,一个是hover层canvas,第二个canvas就是使用refreshHover
方法。
refreshHover
(Painter.js)
1 | refreshHover: function() { |
参考阅读: